/*
 * @Author: 刘岩 15136056318@163.com
 * @Date: 2023-11-04 08:55:55
 * @LastEditors: LiuYan 15136056318@163.com
 * @LastEditTime: 2023-12-01 17:40:59
 * @FilePath: \react-template_pc\src\hooks\index.tsx
 * @Description: hooks
 */
import { type ReactElement, Suspense, lazy, useState } from 'react'
import { useLocation, useNavigate, useParams, useSearchParams } from 'react-router-dom'
import routes from '@/routers'
import type { RoutesType, MetaType } from '@/routers/data'
import type { ReactiveArgs, RouterType } from './data'
import { queryToString } from './utils'
// glob 动态导入
const modulesRoute = import.meta.glob('@/pages/*/*')
// 懒加载组件
export const useLazy = (path: string, Fallback?: JSX.Element): ReactElement => {
  // 匹配相应的路径
  const Component = lazy(() => modulesRoute[path]() as any)
  return (
    <Suspense fallback={Fallback ?? <></>}>
      <Component />
    </Suspense>
  )
}

let meta: MetaType = {}
// 获取路由自定义元信息
const routesRecurve = (routers: RoutesType[], path: string) => {
  routers.forEach(item => {
    if (item.path == path) meta = { ...item.meta }
    if (item.children) routesRecurve(item.children, path)
  })
}
/**
 * @description: 获取所有路由元信息
 * @param {boolean} isCustomParams 是否获取自定义信息
 * @return {*}
 */
export const useRoute = (isCustomParams: boolean = false) => {
  const location = useLocation()
  const params = useParams()
  const [searchParams, setSearchParams] = useSearchParams()
  const query: any = {}
  for (const key of searchParams.keys()) {
    query[key] = searchParams.get(key)
  }
  isCustomParams ? routesRecurve(routes, location.pathname) : (meta = {})
  return {
    ...location,
    params,
    query,
    setSearchParams,
    meta,
  }
}

/**
 * @description: 封装跳转路由
 * @return {*}
 */
export const useRouter = (): RouterType => {
  const navigate = useNavigate()
  const router: RouterType = {
    push: params => {
      const paramsTemp = queryToString(params)
      typeof params != 'string' && params?.target == '_blank'
        ? window.open(`#${paramsTemp}`, '_blank')
        : navigate(paramsTemp)
    },
    replace: params => {
      const paramsTemp = queryToString(params)
      typeof params != 'string' && params?.target == '_blank'
        ? window.open(`#${paramsTemp}`, '_blank')
        : navigate(paramsTemp, { replace: true })
    },
    back: () => {
      navigate(-1)
    },
    go: params => {
      navigate(params)
    },
  }
  return router
}
/**
 * @description: 响应式 hooks
 * @param {object} params
 * @return {*}
 */
export function useReactive<T>(params: T): ReactiveArgs<T> {
  const proxy: any = {}
  for (const key in params) {
    const [state, setState] = useState(params[key])
    proxy[key] = () => [state, setState]
    Object.defineProperty(params, key, {
      get: function () {
        return state
      },
      set: function (newValue) {
        setState(newValue)
      },
    })
  }
  proxy.state = params
  return proxy
}
